from zope.interface import implements

from twisted.application import service, internet
from twisted.cred import portal, checkers
from twisted.web import resource, server, util
from twisted.cred.portal import Portal
from twisted.cred.checkers import AllowAnonymousAccess, FilePasswordDB
from twisted.web.woven.guard import UsernamePasswordWrapper, SessionWrapper
from twisted.cred.credentials import IAnonymous

from nevow import rend, tags, appserver, guard, inevow
from nevow.loaders import stan

from meercat.server.nevow.page import Root



class LoginForm(rend.Page):
    """The resource that is returned when you are not logged in"""
    docFactory = stan(tags.html[
        tags.head[tags.title["Not Logged In"]],
        tags.body[
            tags.form(action=guard.LOGIN_AVATAR)[
                tags.table[
                    tags.tr[
                        tags.td[ "Username:" ],
                        tags.td[ tags.input(type='text',name='username') ],
                    ],
                    tags.tr[
                        tags.td[ "Password:" ],
                        tags.td[ tags.input(type='password',name='password') ],
                    ]
                ],
                tags.input(type='submit'),
            ]
        ]
    ])

class LoggedIn(rend.Page):
    """The resource that is returned when you login"""
    docFactory = stan(tags.html[
        tags.head[tags.title["Logged In"]],
        tags.body[
            tags.h3(renderer=tags.directive("welcome")),
            tags.a(href=guard.LOGOUT_AVATAR)["Logout"]
        ]
    ])

    def __init__(self, username, *args, **kw):
        self.username = username
        renderer.Renderer.__init__(self, *args, **kw)

    def render_welcome(self, context, data):
        return context.tag[ "Hello, %s!" % self.username]

    def logout(self):
        print "%s logged out!" % self.username

def noLogout():
    return None


class MeercatRealm(object):
    """A simple implementor of cred's IRealm.
       For web, this gives us the LoggedIn page.
    """
    implements(portal.IRealm)
    
    def __init__(self, jobService, *args, **kwargs):
        super(MeercatRealm, self).__init__(*args, **kwargs)
        self.jobService = jobService

    def requestAvatar(self, avatarId, mind, *interfaces):
        for iface in interfaces:
            if iface is inevow.IResource:
                # do web stuff
                if avatarId is checkers.ANONYMOUS:
                    resc = LoginForm()
                    resc.realm = self
                    return (resource.IResource, resc, noLogout)
                else:
                    resc = Root(self.jobService, avatarId)
                    resc.realm = self
                    return (resource.IResource, resc, noLogout)

        raise NotImplementedError("Can't support that interface.")


def getGuardedSiteResource(jobService, filename, *args, **kwargs):
    realm = MeercatRealm(jobService)
    portal = Portal(realm)
    
    portal.registerChecker(AllowAnonymousAccess(), IAnonymous)
    portal.registerChecker(FilePasswordDB(filename, *args, **kwargs))
    
    return guard.SessionWrapper(UsernamePasswordWrapper(portal))